package com.example.managemyself.util;

import android.content.Context;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.util.Log;
import android.widget.Toast;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.sqlite.db.SupportSQLiteDatabase;

import com.example.managemyself.data.database.AppDatabase;

import java.io.File;

/**
 * 数据库修复工具类
 * 用于处理数据库迁移问题和数据库损坏问题
 */
public class DatabaseRepairHelper {
    
    private static final String TAG = "DatabaseRepairHelper";
    private static final String PREFS_NAME = "database_repair_prefs";
    private static final String KEY_LAST_REPAIR_TIME = "last_repair_time";
    private static final String KEY_REPAIR_COUNT = "repair_count";
    private static final String DATABASE_NAME = "manage_myself_db";
    
    private final Context context;
    private final SharedPreferences prefs;
    
    public DatabaseRepairHelper(Context context) {
        this.context = context.getApplicationContext();
        this.prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
    }
    
    /**
     * 检查并修复数据库问题
     * @return true 如果修复成功或不需要修复，false 如果修复失败
     */
    public boolean checkAndRepairDatabase() {
        try {
            // 尝试获取数据库实例，这会触发迁移
            AppDatabase database = AppDatabase.getInstance(context);
            
            // 简单的数据库连接测试
            database.taskDao().getAllTasks();
            
            Log.d(TAG, "数据库连接正常，无需修复");
            return true;
            
        } catch (Exception e) {
            Log.e(TAG, "数据库连接失败，尝试修复: " + e.getMessage());
            return repairDatabase();
        }
    }
    
    /**
     * 强制修复数据库
     * @return true 如果修复成功，false 如果修复失败
     */
    public boolean repairDatabase() {
        try {
            Log.d(TAG, "开始数据库修复流程");
            
            // 1. 清理数据库实例
            AppDatabase.clearInstance();
            
            // 2. 删除数据库文件（这会触发重新创建）
            boolean deleted = deleteDatabaseFiles();
            
            if (deleted) {
                Log.d(TAG, "数据库文件已删除");
                
                // 3. 重新创建数据库
                AppDatabase database = AppDatabase.getInstance(context);
                
                // 4. 测试数据库连接
                database.taskDao().getAllTasks();
                
                // 5. 记录修复信息
                recordRepairInfo();
                
                Log.d(TAG, "数据库修复成功");
                return true;
            } else {
                Log.e(TAG, "无法删除数据库文件");
                return false;
            }
            
        } catch (Exception e) {
            Log.e(TAG, "数据库修复失败: " + e.getMessage());
            return false;
        }
    }
    
    /**
     * 删除数据库文件
     */
    private boolean deleteDatabaseFiles() {
        try {
            String databaseName = "manage_myself_db";
            File databaseFile = context.getDatabasePath(databaseName);
            File walFile = new File(databaseFile.getPath() + "-wal");
            File shmFile = new File(databaseFile.getPath() + "-shm");
            
            boolean success = true;
            
            if (databaseFile.exists()) {
                success &= databaseFile.delete();
                Log.d(TAG, "删除数据库文件: " + databaseFile.getPath());
            }
            
            if (walFile.exists()) {
                success &= walFile.delete();
                Log.d(TAG, "删除WAL文件: " + walFile.getPath());
            }
            
            if (shmFile.exists()) {
                success &= shmFile.delete();
                Log.d(TAG, "删除SHM文件: " + shmFile.getPath());
            }
            
            return success;
            
        } catch (Exception e) {
            Log.e(TAG, "删除数据库文件时出错: " + e.getMessage());
            return false;
        }
    }
    
    /**
     * 记录修复信息
     */
    private void recordRepairInfo() {
        long currentTime = System.currentTimeMillis();
        int repairCount = prefs.getInt(KEY_REPAIR_COUNT, 0) + 1;
        
        prefs.edit()
                .putLong(KEY_LAST_REPAIR_TIME, currentTime)
                .putInt(KEY_REPAIR_COUNT, repairCount)
                .apply();
        
        Log.d(TAG, "记录修复信息 - 次数: " + repairCount + ", 时间: " + currentTime);
    }
    
    /**
     * 获取修复统计信息
     */
    public RepairInfo getRepairInfo() {
        long lastRepairTime = prefs.getLong(KEY_LAST_REPAIR_TIME, 0);
        int repairCount = prefs.getInt(KEY_REPAIR_COUNT, 0);
        
        return new RepairInfo(lastRepairTime, repairCount);
    }
    
    /**
     * 显示修复结果Toast
     */
    public void showRepairResult(boolean success) {
        if (success) {
            Toast.makeText(context, "数据库修复成功！应用将重新启动。", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(context, "数据库修复失败，请联系技术支持。", Toast.LENGTH_LONG).show();
        }
    }
    
    /**
     * 修复信息数据类
     */
    public static class RepairInfo {
        public final long lastRepairTime;
        public final int repairCount;
        
        public RepairInfo(long lastRepairTime, int repairCount) {
            this.lastRepairTime = lastRepairTime;
            this.repairCount = repairCount;
        }
        
        public boolean hasBeenRepaired() {
            return repairCount > 0;
        }
    }
    
    /**
     * 修复数据库迁移错误
     */
    public static boolean repairDatabaseMigrationError(Context context) {
        try {
            Log.i(TAG, "开始修复数据库迁移错误...");
            
            // 1. 清理现有数据库实例
            AppDatabase.clearInstance();
            
            // 2. 删除数据库文件
            clearDatabaseFiles(context);
            
            // 3. 重新创建数据库
            AppDatabase db = AppDatabase.getInstance(context);
            
            // 4. 验证数据库是否可用
            if (isDatabaseAccessible(db)) {
                Log.i(TAG, "数据库修复成功！");
                return true;
            } else {
                Log.e(TAG, "数据库修复失败：无法访问数据库");
                return false;
            }
            
        } catch (Exception e) {
            Log.e(TAG, "数据库修复过程中发生错误", e);
            return false;
        }
    }
    
    /**
     * 清理数据库文件
     */
    private static void clearDatabaseFiles(Context context) {
        try {
            // 获取数据库文件路径
            File dbFile = context.getDatabasePath(DATABASE_NAME);
            File walFile = new File(dbFile.getPath() + "-wal");
            File shmFile = new File(dbFile.getPath() + "-shm");
            
            // 删除数据库文件
            if (dbFile.exists()) {
                boolean deleted = dbFile.delete();
                Log.d(TAG, "数据库文件删除: " + deleted);
            }
            
            // 删除WAL文件
            if (walFile.exists()) {
                boolean deleted = walFile.delete();
                Log.d(TAG, "WAL文件删除: " + deleted);
            }
            
            // 删除SHM文件
            if (shmFile.exists()) {
                boolean deleted = shmFile.delete();
                Log.d(TAG, "SHM文件删除: " + deleted);
            }
            
        } catch (Exception e) {
            Log.e(TAG, "清理数据库文件时发生错误", e);
        }
    }
    
    /**
     * 检查数据库是否可访问
     */
    private static boolean isDatabaseAccessible(AppDatabase database) {
        try {
            // 尝试执行一个简单的查询
            database.getOpenHelper().getReadableDatabase().execSQL("SELECT 1");
            return true;
        } catch (Exception e) {
            Log.e(TAG, "数据库不可访问", e);
            return false;
        }
    }
    
    /**
     * 检查特定表是否存在
     */
    public static boolean tableExists(SupportSQLiteDatabase database, String tableName) {
        try {
            android.database.Cursor cursor = database.query(
                "SELECT name FROM sqlite_master WHERE type='table' AND name=?",
                new Object[]{tableName}
            );
            boolean exists = cursor.getCount() > 0;
            cursor.close();
            return exists;
        } catch (Exception e) {
            Log.e(TAG, "检查表存在性时发生错误: " + tableName, e);
            return false;
        }
    }
    
    /**
     * 检查特定列是否存在
     */
    public static boolean columnExists(SupportSQLiteDatabase database, String tableName, String columnName) {
        try {
            android.database.Cursor cursor = database.query("PRAGMA table_info(" + tableName + ")");
            boolean exists = false;
            if (cursor != null) {
                while (cursor.moveToNext()) {
                    String name = cursor.getString(1); // column_name is at index 1
                    if (columnName.equals(name)) {
                        exists = true;
                        break;
                    }
                }
                cursor.close();
            }
            return exists;
        } catch (Exception e) {
            Log.e(TAG, "检查列存在性时发生错误: " + tableName + "." + columnName, e);
            return false;
        }
    }
    
    /**
     * 安全地添加列
     */
    public static void safeAddColumn(SupportSQLiteDatabase database, String tableName, 
                                   String columnName, String columnDefinition) {
        try {
            if (!columnExists(database, tableName, columnName)) {
                database.execSQL("ALTER TABLE " + tableName + " ADD COLUMN " + columnName + " " + columnDefinition);
                Log.d(TAG, "成功添加列: " + tableName + "." + columnName);
            } else {
                Log.d(TAG, "列已存在，跳过添加: " + tableName + "." + columnName);
            }
        } catch (Exception e) {
            Log.e(TAG, "添加列时发生错误: " + tableName + "." + columnName, e);
        }
    }
    
    /**
     * 获取数据库版本
     */
    public static int getDatabaseVersion(Context context) {
        try {
            AppDatabase db = AppDatabase.getInstance(context);
            return db.getOpenHelper().getReadableDatabase().getVersion();
        } catch (Exception e) {
            Log.e(TAG, "获取数据库版本失败", e);
            return -1;
        }
    }
    
    /**
     * 强制重建数据库
     */
    public static boolean forceRebuildDatabase(Context context) {
        try {
            Log.w(TAG, "开始强制重建数据库...");
            
            // 1. 关闭并清理现有数据库
            AppDatabase.clearInstance();
            
            // 2. 删除所有数据库文件
            clearDatabaseFiles(context);
            
            // 3. 创建新的数据库实例
            AppDatabase newDb = Room.databaseBuilder(
                context.getApplicationContext(),
                AppDatabase.class,
                DATABASE_NAME
            ).fallbackToDestructiveMigration()
             .build();
            
            // 4. 验证新数据库
            boolean accessible = isDatabaseAccessible(newDb);
            
            if (accessible) {
                Log.i(TAG, "数据库强制重建成功！");
            } else {
                Log.e(TAG, "数据库强制重建失败！");
            }
            
            return accessible;
            
        } catch (Exception e) {
            Log.e(TAG, "强制重建数据库时发生错误", e);
            return false;
        }
    }
} 